export class Util {
	/**
	 * 通过元素id查找元素
	 * @param idSelector
	 * @param create
	 * @param empty
	 * @returns {Promise<HTMLElement>}
	 */
	async findOrCreateDom(idSelector, create = true, empty = true) {
		let dom = document.getElementById(idSelector);
		if (!dom) {
			if (create) {
				dom = document.createElement('div');
				dom.setAttribute('id', idSelector);
				document.getElementById('app').appendChild(dom);
			} else {
				return undefined;
			}
		}

		const style = dom.style;
		style.width = '100%';
		style.height = '100%';
		style.position = 'relative';

		if (empty) dom.innerHTML = '';

		return dom;
	}

	/**
	 * 校验相机参数是否合法
	 * @param cameraParams
	 * @returns {boolean}
	 */
	validateCameraParams(cameraParams) {
		if (!cameraParams || !cameraParams.toString() === '[object object]') return false;
		const keys = Object.keys(cameraParams);
		return ['lon', 'lat', 'height', 'heading', 'pitch'].every((item) => keys.includes(item));
	}

	/**
	 * 校验modelo相机参数是否合法
	 * @param cameraParams
	 * @returns {boolean}
	 */
	validateModeloCameraParams(cameraParams) {
		if (!cameraParams || !cameraParams.toString() === '[object object]') return false;
		const keys = Object.keys(cameraParams);
		return ['fov', 'distance', 'phi', 'theta', 'at'].every((item) => keys.includes(item));
	}

	/**
	 * 对象合并
	 * @param target {object}
	 * @param source {object}
	 * @returns {*}
	 */
	merage(target, source) {
		for (const key in source) {
			if (Object.prototype.hasOwnProperty.call(source, key)) {
				if (source[key] === undefined) {
					target[key] = source[key];
					continue;
				}
				if (source[key].toString() === '[object Object]') {
					this.merage(target[key], source[key]);
				} else {
					target[key] = source[key];
				}
			}
		}
		return target;
	}

	/**
	 * 测量单位转换
	 * @param val {Number}
	 * @param type {String}
	 * @param unit {String}
	 * @param float {Number}
	 * @param scientific {Object}
	 * @returns {string}
	 */
	unitFormat(val, type, unit, float, scientific) {
		if (+val === 0) return `${val}${unit}`;
		let symbols = '';
		if (val < 0) {
			symbols = '-';
			val = Math.abs(val);
		}

		if (type === 'length') {
			switch (unit) {
				case 'mm':
					val = val * 1000;
					break;
				case 'cm':
					val = val * 100;
					break;
				case 'm':
					val;
					break;
				case 'km':
					val = val / 1000;
					break;
				default:
					val;
			}
		}
		if (type === 'elevation') {
			switch (unit) {
				case 'mm':
					val = val * 1000;
					break;
				case 'cm':
					val = val * 100;
					break;
				case 'm':
					val = (val * 100) / 100;
					break;
				case 'km':
					val = val / 1000;
					break;
				default:
					val = (val * 100) / 100;
					break;
			}
		}
		if (type === 'area') {
			switch (unit) {
				case 'mm²':
					val = val * 1000000;
					break;
				case 'cm²':
					val = val * 10000;
					break;
				case 'm²':
					val;
					break;
				case 'hm²':
					val = val / 10000;
					break;
				case 'km²':
					val = val / 1000000;
					break;
				default:
					val;
			}
		}
		if (type === 'volume') {
			switch (unit) {
				case 'mm³':
					val = val * 1000000000;
					break;
				case 'cm³':
					val = val * 1000000;
					break;
				case 'L':
					val = val * 1000;
					break;
				case 'm³':
					val;
					break;
				default:
					val;
			}
		}

		// 科学计数法
		scientific = scientific || { flag: false, type: 'e+' };
		let sign;
		switch (scientific.type) {
			case '1.234E4':
				sign = 'E';
				break;
			case '1.234e4':
				sign = 'e';
				break;
			default:
				sign = 'e+';
				break;
		}
		const decimal = Math.floor(Math.log10(val));
		const integer = (val * Math.pow(10, -decimal)).toFixed(3);
		const string = `${symbols}${integer}${sign}${decimal}${unit}`;

		return scientific.flag ? string : `${symbols}${val.toFixed(float)}${unit}`;
	}
}
